﻿using Microsoft.Xna.Framework;

namespace RainEngine.Rendering
{
    /// <summary>
    /// 定义使用何种方法进行剔除。
    /// </summary>
    public enum CullingMethod
    {
        /// <summary>
        /// 不进行剔除计算。
        /// </summary>
        NoCulling,

        /// <summary>
        /// 视锥体剔除，所有在视锥体之外的对象将被剔除。
        /// </summary>
        Frustum,

        /// <summary>
        /// 这是默认的方法。类似于<see cref="Frustum"/>剔除，只不过这种剔除中，真实远裁平面(<see cref="CameraSceneNode.internalFarPlane"/>)被设置为一个很大的数，可以绘制非常远的对象。
        /// 如果对象在视锥体之外或距离大于FarPlane则被剔除。通常如地形之类的对象不会被剔除，以防止当相机移动时，地形的几何体突然出现在视野中。
        /// </summary>
        FarPlaneFrustum,

        /// <summary>
        /// 场景对象由四叉树进行剔除，还未实现。
        /// </summary>
        QuadTree,
    }

    /// <summary>
    /// 几何体剔除的数据容器。
    /// </summary>
    public class CullingInfo
    {
        /// <summary>
        /// 创建一个新CullingInfo对象。
        /// </summary>
        public CullingInfo() 
        {
            this.CullingMethod = CullingMethod.NoCulling;            
            this.FarPlane = 0;
            this.CameraPosition = Vector3.Zero;
        }
        /// <summary>
        /// 创建一个新CullingInfo对象。
        /// </summary>
        /// <param name="method">剔除方法</param>
        /// <param name="frustum">相机的真实视锥体，远裁平面距离很大</param>
        /// <param name="farPlane">相机的逻辑视锥体，这个值在创建相机时由用户指定</param>
        /// <param name="cameraPosition">当前相机位置</param>
        public CullingInfo(CullingMethod method, BoundingFrustum frustum, float farPlane, ref Vector3 cameraPosition)
        {
            this.CullingMethod = method;
            this.BoundingFrustum = frustum;
            this.FarPlane = farPlane;
            this.CameraPosition = cameraPosition;
        }

        /// <summary>
        /// 当前RenderingPass使用的剔除方法。
        /// </summary>
        public CullingMethod    CullingMethod;
        /// <summary>
        /// 相机的包围视锥体。它是真实包围视锥体，比逻辑视锥体大10倍。
        /// </summary>
        public BoundingFrustum  BoundingFrustum;
        /// <summary>
        /// 相机的逻辑远裁平面。用来基于它进行基于距离的剔除，有些节点虽然在视锥体中，但距离太远，也应该将它剔除提高性能
        /// </summary>
        public float            FarPlane;
        /// <summary>
        /// 相机的位置。
        /// </summary>
        public Vector3          CameraPosition;
    }
}
